<?php
/**
 * Base
 *
 * All processor should extends this base object as node.
 *
 * @author  Badrus Said <badrus.said@gmail.com>
 * @since   gop1.0
 */
abstract class gop_Base {
    private $_namespace = null, $_caller = null,
        $_result = null, $_return = false, $_continue = 0, $_break = 0, $_chain = null, $_name,
        $_arguments = array();
    public function __construct($_namespace, $_name, array $_arguments = null, $_chain = null) {
        $this->_namespace = $_namespace;
        $this->_name = $_name;
        if (!is_null($_chain) && is_int($_chain)) $this->_chain = $_chain;
        if (!is_null($_arguments)) {
            foreach($_arguments as $k => $v) {
                if ($k == "_result") $this->_result = $v; else $this->_arguments[$k] = $v;
            }
        }
    }
    public function __isset($k) {return array_key_exists($k, $this->_arguments);}
    public function __set($k, $v) {$this->_arguments[$k] = $v;}
    public function __get($k) {
        if (!array_key_exists($k, $this->_arguments)) throw new Exception("Undefined property: ".$this->getName()."::".$k);
        return $this->_arguments[$k];
    }
    public function getContext() {return gop_Context::getContext($this->_namespace);}
    public function setCaller(gop_Base $_caller = null) {$this->_caller = $_caller;}
    public function getCaller() {return $this->_caller;}
    public function interuptExec() {$this->_return = true;}
    public function setBreak($x) {$this->_break = $x;}
    public function getBreak() {return $this->_break;}
    public function setContinue($x) {$this->_continue = $x;}
    public function getContinue() {return $this->_continue;}
    public function getReturn() {return $this->_return;}
    public function getResult() {return $this->_result;}
    public function setResult($_result, $nestedLevel = 1) {
        $this->_result = $_result;
        if ($nestedLevel > 0) {
        if (!is_null($this->_caller)) {
            $this->_caller->setResult($this->getResult(), $nestedLevel - 1);
        }}
    }
    public function getName() {return $this->_name;}
    public function chainExec() {
        if (!$this->_return && !is_null($this->_chain)) {
            if (!$this->getContext()->hasCallee($this->_chain)) {
                die("ChainExecException: no chain node: ".$this->_chain);
            }
            $this->getContext()->getCallee($this->_chain)->execute($this);
            if ($this instanceof gop_BaseIterator) {
                if ($this->_continue) $this->interuptContinue();
                if ($this->_break) $this->interuptBreak();
            }
        }
    }
}
?>